import struct

from lib import stdlib
from exception import BGPError

HeaderSize = 19
BGPMaxHeaderSize = 4096
BGPMinHeaderSize = HeaderSize

class MessageType(object):
   def __init__(self):
      self._mesgtype = stdlib.enum('UNKNOWN', 'OPEN', 'UPDATE', 'NOTIFICATION',
            'KEEPALIVE', 'ROUTE_REFRESH')

   def __getattr__(self, name):
      return getattr(self._mesgtype, name)

class message(object):
   def __init__(self, Message = None):
      self._bgptype = MessageType()
      self._mesg = None
      self._mesglen = 0
      self._mesgtype = self._bgptype.UNKNOWN

      (self._mesg, self._mesglen, self._mesgtype) = self._parse(Message)

   length = property(fget = lambda self: self._length)
   mesgtype = property(fget = lambda self: self._mesgtype)

   def get(self):
      return str(self._mesg).encode('utf-8')

   def _parse(self, Message):
      mesg = None
      mesglen = 0
      mesgtype = MessageType().UNKNOWN
      if Message:
         (mesg, mesglen, mesgtype) = struct.unpack(">16cHB", Message)
         if self._mesglen < 19:
            self._error("Invalid BGP message length!")

         if (self._mesgtype < 1) or (self._mesgtype > 5)
            self._error("Invalid BGP message type!")

      return (mesg, mesglen, mesgtype)

   def new(self, Message, ASN = False, RouteLen = 0):
      retval = None
      try:
         (mesg, length, mesgtype) = self._parse(Message)
      except BGPError as err:
         raise
      else:
         retval = bgpmessage(mesgtype, Message, ASN, RouteLen)

      return retval
